require 'rubygems'
require 'win32console'
include Win32::Console::ANSI

# ANSI Escape Color List
# Intensity    0        1        2        3        4        5        6        7
# ------------------------------------------------------------------------------------
# Normal       Black    Red      Green    Yellow   Blue     Magenta  Cyan     White
# Bright       Black    Red      Green    Yellow   Blue     Magenta  Cyan     White

class String
    ANSI_DARK_RED = "\e[0m\e[31m"
    ANSI_DARK_GREEN = "\e[0m\e[32m"
    ANSI_DARK_YELLOW = "\e[0m\e[33m"
    ANSI_DARK_BLUE = "\e[0m\e[34m"
    ANSI_DARK_MAGENTA = "\e[0m\e[35m"
	ANSI_DARK_CYAN = "\e[0m\e[36m"
	ANSI_DARK_WHITE = "\e[0m\e[37m"
    ANSI_RED = "\e[1m\e[31m"
    ANSI_GREEN = "\e[1m\e[32m"
    ANSI_YELLOW = "\e[1m\e[33m"
    ANSI_BLUE = "\e[1m\e[34m"
    ANSI_MAGENTA = "\e[1m\e[35m"
	ANSI_CYAN = "\e[1m\e[36m"
	ANSI_WHITE = "\e[1m\e[37m"
	ANSI_END = "\e[0m"
	
    def dark_red; colorize(self, "#{ANSI_DARK_RED}"); end
    def dark_green; colorize(self, "#{ANSI_DARK_GREEN}"); end
    def dark_yellow; colorize(self, "#{ANSI_DARK_YELLOW}"); end
    def dark_blue; colorize(self, "#{ANSI_DARK_BLUE}"); end
    def dark_magenta; colorize(self, "#{ANSI_DARK_MAGENTA}"); end
	def dark_cyan; colorize(self, "#{ANSI_DARK_CYAN}"); end
	def dark_white; colorize(self, "#{ANSI_DARK_WHITE}"); end
    def red; colorize(self, "#{ANSI_RED}"); end
    def green; colorize(self, "#{ANSI_GREEN}"); end
    def yellow; colorize(self, "#{ANSI_YELLOW}"); end
    def blue; colorize(self, "#{ANSI_BLUE}"); end
    def magenta; colorize(self, "#{ANSI_MAGENTA}"); end
	def cyan; colorize(self, "#{ANSI_CYAN}"); end
	def white; colorize(self, "#{ANSI_WHITE}"); end
    def colorize(text, color_code)  "#{color_code}#{text}#{ANSI_END}" end
end

def locate(path_list, to_find)
	found = false
	pathext = ENV['PATHEXT'].upcase.split(';')
	
	path_list.each do |path|
		if path.length != 0
			if File.exist?(path) and File.directory?(path)
				dir = Dir.new(path)
				dir.each do |file|
					if file == to_find
						found = true
					elsif to_find == File.basename(file, File.extname(file))
						if pathext.include?(File.extname(file).upcase)
							found = true
						end
					end
					
					if found
						finding = dir.path + "\\" + file
						return finding
					end
				end
			end
		end
	end
	return ""
end

# Join string in a array
def join(arr, index, length)
	s = ""
	if index + length > arr.size
		length = arr.size - index
	end
	
	while length > 0
		if s.length == 0
			s = arr[index]
		else
			s = s + " " + arr[index]
		end
		index = index + 1
		length = length - 1
	end
	return s
end

def show_end()
	puts String::ANSI_MAGENTA
	print "\04"
	print String::ANSI_END
end

def run_in_color(cmd)
	print String::ANSI_DARK_CYAN
	system(cmd)
	print String::ANSI_END
end

def execute(src, args)
	ext = File.extname(src).downcase
	bas = File.basename(src, ext)
	
	if not File.exist?(src)
		puts "File not found: " + src
		exit
	else
		if args.length > 0
			puts "Running `#{src} #{args}`".white
			cmd = "#{src} #{args}"
		else
			puts "Running `#{src}`".white
			cmd = "#{src}"
		end
	end

	case ext
	when ".exe"
		run_in_color(cmd)
	when ".bat"
		run_in_color(cmd)
	when ".vbs"
		cmd = "cscript //nologo #{cmd}"
		run_in_color(cmd)
	when ".js"
		cmd = "cscript //nologo #{cmd}"
		run_in_color(cmd)
	when ".rb"
		cmd = "ruby #{cmd}"
		run_in_color(cmd)
	when ".c"
		cmd = "gcc #{src} -o #{bas}.exe"
		system(cmd)
		if $? == 0
			cmd = "#{bas}.exe #{args}"
			run_in_color(cmd)
		end
	when ".cpp"
		cmd = "g++ #{src} -o #{bas}.exe"
		system(cmd)
		if $? == 0
			cmd = "#{bas}.exe #{args}"
			run_in_color(cmd)
		end
	when ".cs"
		cmd = "csc /nologo #{src}"
		system(cmd)
		if $? == 0
			cmd = "#{bas}.exe #{args}"
			run_in_color(cmd)
		end
	when ".d"
		cmd = "dmd #{src}"
		system(cmd)
		if $? == 0
			cmd = "#{bas}.exe #{args}"
			run_in_color(cmd)
		end
	when ".java"
		cmd = "javac #{src}"
		system(cmd)
		if $? == 0
			cmd = "java #{bas}"
			run_in_color(cmd)
		end
	else
		puts "Unrecognized file type: " + ext
	end
end

def main
	if ARGV.size < 1
		puts "run - Run a source file or an executable"
		puts "usage: run SOURCE_FILE [arg1 [arg2 ...]]"
		exit
	end

	src = ARGV[0]
	src = locate(('.;' + ENV['PATH']).split(';'), src)
	
	if src.length == 0
		puts "File not found: " + ARGV[0]
		return
	end
	
	args = join(ARGV, 1, ARGV.size)
	execute(src, args)
	show_end
end

main

